import AppError from "@/shared/app-error";
import responseService from "./service/response-service";
import log from "./log";

type Success<T> = { ok: true; data: T };
type Failure = { ok: false; code: ErrorCode; message: string };

type ActionResult<T> = Success<T> | Failure;

export async function wrapAction<T>(fn: () => Promise<T>): Promise<ActionResult<T>> {
  try {
    const t = await fn();
    return { ok: true, data: t };
  } catch (err) {
    if (err instanceof AppError) {
      log.error("action AppError", err)
      return { ok: false, code: err.code, message: err.message };
    } else {
      log.error("action unhandled error", err)
      return { ok: false, code: "ERR_UNHANDLED", message: "未知错误" };
    }
  }
}

type RouteFn<T> = (opts: { headers: [string, string][] }) => Promise<T>;

export async function wrapRoute<T>(fn: RouteFn<T>): Promise<Response> {
  try {
    const respOpts = { headers: [] };
    const data = await fn(respOpts);
    return responseService.ok({ body: data, headers: respOpts.headers });
  } catch (err) {
    if (err instanceof AppError) {
      log.error("route AppError", err)
      return responseService.appError(err);
    } else {
      log.error("route AppError", err)
      return responseService.internalServerError({ cause: err, message: "未知错误" });
    }
  }
}
